package org.jeecg.modules.iot.middleware.processor.powerOperate;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.iot.model.power.TaitModbusPowerResponse;
import org.springframework.stereotype.Component;

import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 泰比特MODBUS协议解析器
 */
@Slf4j
@Component("taitModbusParser")
public class TaitModbusParser {

    /**
     * 解析泰比特MODBUS协议的电池数据
     *
     * @param data MODBUS响应数据，例如："03 03 A2 00 00 50 67 AC 03 03 A0 64 01 00 00..."
     * @return 解析后的电池数据
     */
    /**
     * 解析泰比特MODBUS协议的电池数据
     *
     * @param data MODBUS响应数据，例如："03 03 A2 00 00 50 67 AC 03 03 A0 64 01 00 00..."
     * @return 解析后的电池数据
     */
    public TaitModbusPowerResponse parseBatteryData(byte[] data, Integer startAdrres) {
        int startingAddress=0xA200;
        if (startAdrres!=null){
            startingAddress=startAdrres;
        }

        // 使用 Unpooled.wrappedBuffer 创建 ByteBuf
        ByteBuf buf = Unpooled.wrappedBuffer(data);

        // 创建一个 TaitModbusResponse 对象，用于存储所有解析到的数据
        TaitModbusPowerResponse response = new TaitModbusPowerResponse();


        // 检查是否足够的字节读取从机地址
        if (buf.readableBytes() < 1) {
            return  null;
        }
        int slaveAddress = buf.readByte() & 0xFF;

        // 检查是否足够的字节读取功能码
        if (buf.readableBytes() < 1) {
            return  null;
        }
        response.setSlaveAddress(slaveAddress);




        // 检查是否足够的字节读取数据字节数
        if (buf.readableBytes() < 1) {
            return  null;
        }
        // 读取功能码
        int functionCode = buf.readByte() & 0xFF;
        response.setFunctionCode(functionCode);
        System.out.println("slaveAddress 从机地址"+slaveAddress+",functionCode 功能码"+functionCode);


        // 读取数据字节数
        int dataLength = buf.readByte() & 0xFF;
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
        String formattedDateTime = now.format(formatter);
        // 将 dataLength 转换为十六进制字符串
        String hexDataLength = Integer.toHexString(dataLength).toUpperCase();
        // 组合输出字符串
        String outputString = "865376074560937 数据 " + hexDataLength + " 时间: " + formattedDateTime;
        System.out.println(outputString);
        // 检查是否足够的字节读取数据部分
        if (buf.readableBytes() < dataLength) {
            return  null;
        }
        byte[] dataArray = new byte[dataLength];
        buf.readBytes(dataArray);
        // 读取数据部分 (不包括CRC)
        //ByteBuf dataBuf = buf.readSlice(dataLength);


        // 读取CRC校验码
        byte crcHigh = buf.readByte();
        byte crcLow = buf.readByte();

        // 计算校验码
        byte[] calculatedCRC = calculateCRC16(data, 0,   data.length - 2 );

        //parseDataPacket(response, functionCode, dataArray,dataLength, startingAddress);
        // 比较计算得到的校验码和数据包中的校验码
        if (calculatedCRC[0] == crcHigh && calculatedCRC[1] == crcLow) {
            // 校验码匹配，数据包完整

            // 解析数据包并将数据存入 response 对象
             parseDataPacket(response,slaveAddress, functionCode, dataArray,dataLength, startingAddress);
        } else {
            // 校验码不匹配，数据包错误
            System.err.println("CRC校验失败！");
        }

        // 释放 ByteBuf
        buf.release();

        // 返回解析后的 TaitModbusResponse 对象
        return response;
    }

    /**
     * 解析单个数据包并将数据存入 response 对象
     *
     * @param response   TaitModbusResponse 对象，用于存储解析到的数据
     * @param packetData 数据包字节数组
     */
    private void parseDataPacket(TaitModbusPowerResponse response, int slaveAddress, int functionCode, byte[] dataBuf, int dataLength, int startingAddress) {

        // 根据功能码解析数据
        long startTime = System.nanoTime();
        ByteBuf buf = Unpooled.wrappedBuffer(dataBuf);
        if (slaveAddress==0x01){
            response.setDeviceId(asciiToString(dataBuf));
        }else if (slaveAddress==0x03){
            if (functionCode == 0x03) {
                // 读多个寄存器，解析数据
                if (0xA00D == startingAddress ){
                    response.setDeviceName(asciiToString(dataBuf));
                }else {
                    // 读多个寄存器,解析数据
                    buf.readerIndex(0); // 重置 readerIndex
                    parseDataByAddress(response, buf, startingAddress, dataLength, dataBuf.length);
                }
                // response.setDeviceName(asciiToString(dataBuf)); // 读取设备名称 "KAM123456"
                //response.setSoftwareVersion(dataBuf.readByte() + "." + dataBuf.readByte() + "." + dataBuf.readByte()); // 读取软件版本 "0.0.0"
                //response.setProtocolVersion(dataBuf.readByte() + "." + dataBuf.readByte() + "." + dataBuf.readByte()); // 读取协议版本 "0.0.0"




            }
        }
        buf.release();
        long endTime = System.nanoTime();
        System.out.println("解析处理时间-----------Storage time: " + (endTime - startTime) / 1e6 + " ms");
    }
    private byte[] calculateCRC16(byte[] data, int start, int len) {
        int crc = 0xFFFF;
        for (int i = start; i < start + len; i++) {
            crc ^= (data[i] & 0xFF);
            for (int j = 0; j < 8; j++) {
                if ((crc & 0x0001) != 0) {
                    crc >>= 1;
                    crc ^= 0xA001;
                } else {
                    crc >>= 1;
                }
            }
        }
        return new byte[]{(byte) (crc & 0xFF), (byte) ((crc >> 8) & 0xFF)};
    }
    private void parseDataByAddress(TaitModbusPowerResponse response, ByteBuf dataBuf, int startingAddress, int dataLength, int totalLength) {
        // 计算起始地址偏移量
        int offset = (startingAddress - 0xA200) * 2; // 每个寄存器占2个字节

        // 如果起始地址偏移量超出数据范围，则不进行解析
        if (offset < 0 || offset >= totalLength) {
            return;
        }



        // 从偏移量开始读取数据
        dataBuf.readerIndex(offset);
        /*UnsignedByte 8位 UnsignedShort  16 UnsignedInt 32*/
        // 解析数据，直到数据读取完毕
        outer:
        while (dataBuf.readerIndex() < totalLength) {
            int currentAddress = startingAddress + (dataBuf.readerIndex() - offset) / 2;
            switch (currentAddress) {
                case 0xA200:
                    // 解析电池组健康百分比和BMS是否持续输出电压
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池组健康百分比和BMS是否持续输出电压,地址:0xA200");
                        break outer;
                    }
                    response.setBatteryPackHealth(dataBuf.readUnsignedByte());
                    response.setBmsOutputVoltage(dataBuf.readUnsignedByte() == 1);
                    System.out.println("解析0xA200");
                    break;
                case 0xA201:
                    // 解析BMS输出延时
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析BMS输出延时,地址:0xA201");
                        break outer;
                    }
                    response.setBmsOutputDelay(dataBuf.readUnsignedShort());
                    System.out.println("解析0xA201");
                    break;
                case 0xA202:
                    // 解析电池组内部温度
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池组内部温度,地址:0xA202");
                        break outer;
                    }
                    response.setBatteryPackTemperature((float) (dataBuf.readUnsignedShort() * 0.1f- 273.15));
                    System.out.println("解析0xA202");
                    break;
                case 0xA203:
                    // 解析电池组总电压
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池组总电压,地址:0xA203");
                        break outer;
                    }
                    response.setBatteryPackVoltage( dataBuf.readUnsignedInt() * 0.001f);
                    System.out.println("解析0xA203");
                    break;
                case 0xA205:
                    // 解析电池实时电流
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池实时电流,地址:0xA205");
                        break outer;
                    }
                    response.setBatteryCurrent(dataBuf.readInt() * 0.001f);
                    System.out.println("解析0xA205");
                    break;
                case 0xA207:
                    // 解析电池相对容量百分比和电池绝对容量百分比
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池相对容量百分比和电池绝对容量百分比,地址:0xA207");
                        break outer;
                    }
                    response.setBatteryRelativeCapacity(dataBuf.readUnsignedByte());
                    response.setBatteryAbsoluteCapacity(dataBuf.readUnsignedByte());
                    System.out.println("解析0xA207");
                    break;
                case 0xA208:
                    // 解析电池剩余容量
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池剩余容量,地址:0xA208");
                        break outer;
                    }
                    response.setBatteryRemainingCapacity(dataBuf.readUnsignedInt());
                    System.out.println("解析0xA208");
                    break;
                case 0xA20A:
                    // 解析电池满电容量
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池满电容量,地址:0xA20A");
                        break outer;
                    }
                    response.setBatteryFullCapacity(dataBuf.readUnsignedInt());
                    System.out.println("解析0xA20A");
                    break;
                case 0xA20C:
                    // 解析电池循环次数
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池循环次数,地址:0xA20C");
                        break outer;
                    }
                    response.setBatteryCycleCount(dataBuf.readUnsignedInt());
                    System.out.println("解析0xA20C");
                    break;
                case 0xA20E:
                    // 保留字段，跳过
                    //dataBuf.skipBytes(4);
                    //response.setBatteryRemainingCapacity();
                    System.out.println("解析0xA20E"+dataBuf.readUnsignedShort());
                    break;
                case 0xA210:
                    // 解析高16组每节电池电压
                    if (dataBuf.readableBytes() < 32) { // 16 * 2 (short)
                        System.err.println("数据长度不足，无法解析高16组每节电池电压,地址:0xA210");
                        break outer;
                    }
                    for (int i = 0; i < 16; i++) {
                        response.setHighGroupCellVoltage(i, dataBuf.readUnsignedShort() * 0.001f);
                    }
                    System.out.println("解析0xA210");
                    break;
                case 0xA220:
                    // 解析低16组每节电池电压
                    if (dataBuf.readableBytes() < 32) { // 16 * 2 (short)
                        System.err.println("数据长度不足，无法解析低16组每节电池电压,地址:0xA220");
                        break outer;
                    }
                    for (int i = 0; i < 16; i++) {
                        response.setLowGroupCellVoltage(i, dataBuf.readUnsignedShort() * 0.001f);
                    }
                    System.out.println("解析0xA220");
                    break;
                case 0xA230:
                    // 解析电池当前充电间隔时间
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池当前充电间隔时间,地址:0xA230");
                        break outer;
                    }
                    response.setCurrentChargingInterval(dataBuf.readUnsignedShort());
                    System.out.println("解析0xA230");
                    break;
                case 0xA231:
                    // 解析电池最大充电间隔时间
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池最大充电间隔时间,地址:0xA231");
                        break outer;
                    }
                    response.setMaxChargingInterval(dataBuf.readUnsignedShort());
                    System.out.println("解析0xA231");
                    break;
                case 0xA232:
                    // 解析电池允许最大放电电流
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池允许最大放电电流,地址:0xA232");
                        break outer;
                    }
                    response.setMaxDischargeCurrent(dataBuf.readUnsignedInt() * 0.001f);
                    System.out.println("解析0xA232");
                    break;
                case 0xA234:
                    // 解析电池允许最大充电电流
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池允许最大充电电流,地址:0xA234");
                        break outer;
                    }
                    response.setMaxChargeCurrent(dataBuf.readUnsignedInt() * 0.001f);
                    System.out.println("解析0xA234");
                    break;
                case 0xA236:
                    // 保留字段，跳过
                    dataBuf.skipBytes(4);
                    System.out.println("解析0xA236");
                    break;
                case 0xA238:
                    // 解析电池状态信息
                    if (dataBuf.readableBytes() < 16) {
                        System.err.println("数据长度不足，无法解析电池状态信息,地址:0xA238");
                        break outer;
                    }
                    byte[] data = new byte[16];
                    dataBuf.readBytes(data);
                    parseBatteryStatus(data, response);
                    System.out.println("解析0xA238");
                    break;
                case 0xA240:
                    // 解析电芯型号
                    if (dataBuf.readableBytes() < 16) {
                        System.err.println("数据长度不足，无法解析电芯型号,地址:0xA240");
                        break outer;
                    }
                    response.setCellModel(dataBuf.readBytes(16).toString(StandardCharsets.UTF_8));
                    System.out.println("解析0xA240");
                    break;
                case 0xA248:
                    // 解析电池组内部实时时钟RTC
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池组内部实时时钟RTC,地址:0xA248");
                        break outer;
                    }
                    response.setRtc(dataBuf.readUnsignedInt());
                    System.out.println("解析0xA248");
                    break;
                case 0xA24A:
                    // 解析电池设计容量
                    if (dataBuf.readableBytes() < 2) {
                        System.err.println("数据长度不足，无法解析电池设计容量,地址:0xA24A");
                        break outer;
                    }
                    response.setBatteryDesignCapacity(dataBuf.readUnsignedShort());
                    System.out.println("解析0xA24A");
                    break;
                case 0xA24B:
                    // 解析电池累计放电安时数
                    if (dataBuf.readableBytes() < 4) {
                        System.err.println("数据长度不足，无法解析电池累计放电安时数,地址:0xA24B");
                        break outer;
                    }
                    response.setTotalDischargeAh(dataBuf.readUnsignedInt() * 0.001f);
                    System.out.println("解析0xA24B");
                    break;
                case 0xA24D:
                    // 保留字段，跳过
                    //dataBuf.skipBytes(8);
                    //System.out.println("解析0xA24D");
                    break outer;
                case 0xA00D :

                    break outer;
                default:
                    // 未知地址，跳过相应字节数
                    //dataBuf.skipBytes(2); // 每个寄存器占2个字节
                    break outer;
            }
        }
    }


    private String asciiToString(byte[] ascii) {
       /* StringBuilder sb = new StringBuilder();
        for (byte b : ascii) {
            sb.append((char) b);
        }
        return sb.toString().trim();*/
        return new String(ascii, StandardCharsets.US_ASCII).trim();
    }

    /**
     * 将十六进制字符串转换为字节数组
     *
     * @param hexString 十六进制字符串
     * @return 字节数组
     */
    private byte[] hexStringToByteArray(String hexString) {
      /*  // 移除空格
        hexString = hexString.replaceAll("\\s+", "");

        // 检查字符串长度
        if (hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("Invalid hexadecimal string");
        }

        // 创建字节数组
        byte[] bytes = new byte[hexString.length() / 2];

        // 转换字符串为字节数组
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i + 1), 16));
        }

        return bytes;*/
        return DatatypeConverter.parseHexBinary(hexString.replaceAll("\\s+", ""));
    }



    /**
     * 解析错误状态
     *
     * @param response MODBUS响应数据
     * @param data     原始数据
     * @param offset   偏移量
     */
    private void parseErrorStatus(TaitModbusPowerResponse response, byte[] data, int offset) {
        int byte2 = parseUint8(data, offset);
        response.setProtectionChipError((byte2 & 0x01) != 0);
    }

    /**
     * 解析无符号8位整数
     *
     * @param data   原始数据
     * @param offset 偏移量
     * @return 无符号8位整数
     */
    private int parseUint8(byte[] data, int offset) {
        if (offset < 0 || offset >= data.length) {
            throw new IllegalArgumentException("Offset out of bounds: " + offset);
        }
        return data[offset] & 0xFF;
    }

    /**
     * 解析无符号16位整数
     *
     * @param data   原始数据
     * @param offset 偏移量
     * @return 无符号16位整数
     */
    private int parseUint16(byte[] data, int offset) {
        return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
    }

    /**
     * 解析无符号32位整数
     *
     * @param data   原始数据
     * @param offset 偏移量
     * @return 无符号32位整数
     */
    // ... 其他解析方法（parseUint8, parseUint16, parseUint32, parseInternalStatus, parseErrorStatus）
    private long parseUint32(byte[] data, int offset) {
        return ((data[offset] & 0xFFL) << 24) |
                ((data[offset + 1] & 0xFFL) << 16) |
                ((data[offset + 2] & 0xFFL) << 8) |
                (data[offset + 3] & 0xFFL);
    }

    private void parseBatteryStatus(byte[] data, TaitModbusPowerResponse response) {
        if (data.length != 16) {
            // 处理数据长度错误
            return;
        }

        response.setChargeMosfetOn((data[0] & 0x80) == 0x80);
        response.setDischargeMosfetOn((data[0] & 0x40) == 0x40);
        response.setPreDischargeCircuitOn((data[0] & 0x20) == 0x20);
        response.setPreChargeCircuitOn((data[0] & 0x10) == 0x10);
        response.setChargerConnected((data[0] & 0x08) == 0x08);
        response.setChargerIdentified((data[0] & 0x04) == 0x04);

        response.setBatteryChargingStopped((data[1] & 0x80) != 0);

        response.setProtectionChipError((data[2] & 0x01) != 0);
        response.setCellDropError((data[2] & 0x02) != 0);
        response.setImbalanceError((data[2] & 0x04) != 0);
        response.setEstimateError((data[2] & 0x08) != 0);
        response.setRecordError((data[2] & 0x10) != 0);
        response.setRtcError((data[2] & 0x20) != 0);
        response.setDischargingMosfetError((data[2] & 0x40) != 0);
        response.setChargingMosfetError((data[2] & 0x80) != 0);

        response.setOverChargeError((data[3] & 0x01) != 0);
        response.setPrimaryOverDischargeError((data[3] & 0x02) != 0);
        response.setSecondaryOverDischargeError((data[3] & 0x04) != 0);
        response.setPrimaryOverCurrentError((data[3] & 0x08) != 0);
        response.setSecondaryOverCurrentError((data[3] & 0x10) != 0);
        response.setOverChargeCurrentError((data[3] & 0x20) != 0);
        response.setPreStartFailError((data[3] & 0x40) != 0);
        response.setPreChargeOvertimeWarning((data[3] & 0x80) != 0);

        response.setMosTemperatureSensorError((data[4] & 0x01) != 0);
        response.setCellTemperatureSensorError((data[4] & 0x02) != 0);
        response.setOverDischargeTemperatureError((data[4] & 0x04) != 0);
        response.setOverChargeTemperatureError((data[4] & 0x08) != 0);
        response.setUnderDischargeTemperatureError((data[4] & 0x10) != 0);
        response.setUnderChargeTemperatureError((data[4] & 0x20) != 0);
        response.setOverTemperatureOfDischargeMosfetError((data[4] & 0x40) != 0);
        response.setOverTemperatureOfChargeMosfetError((data[4] & 0x80) != 0);

        response.setOverTemperatureOfPreStartCircuitError((data[5] & 0x01) != 0);
        response.setThirdOverCurrentError((data[5] & 0x10) != 0);
        response.setConfigDataError((data[5] & 0x40) != 0);

        // ... 解析剩余的警告信息 ...

        for (int i = 0; i < 8; i++) {
            response.setBalanceStatus(i, (data[12] & (1 << i)) != 0);
        }
        for (int i = 0; i < 8; i++) {
            response.setBalanceStatus(i + 8, (data[13] & (1 << i)) != 0);
        }
        for (int i = 0; i < 8; i++) {
            response.setBalanceStatus(i + 16, (data[14] & (1 << i)) != 0);
        }
    }



    public static void main(String[] args) {
        // 示例数据
        //String dataStr = "03 03 A0 63 01 00 01 0B C8 00 00 D8 40 00 00 00 00 14 14 00 00 13 7D 02 00 00 5D C0 00 00 00 06 01 13 00 00 0C BA 0C BC 0C B7 0C B6 0C B8 0C B9 0C B7 0C BA 0C B7 0C BA 0C B9 0C B7 0C BB 0C B7 0C B7 0C B6 0C B6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 D8 0B 4F 00 00 86 A0 00 00 EA 60 00 F0 17 E8 C0 80 00 00 00 00 00 00 00 00 00 00 00 00 A5 00 00 4C 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 2E 18 68 CE 5D C0 00 00 FB CC 00 00 00";
        //String dataStr = "03 03 A0 63 01 00 01 0B D5 00 00 DA D4 00 00 00 00 26 26 00 00 24 04 00 00 5D C0 00 00 00 06 02 04 00 00 0C DD 0C E2 0C DF 0C E0 0C E0 0C E0 0C E0 0C E0 0C DF 0C E0 0C DF 0C DF 0C E0 0C DF 0C DF 0C DF 0C E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 EE 0B 4F 00 00 86 A0 00 00 EA 60 00 F0 17 E8 C0 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4C 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 2E 19 28 51 5D C0 00 00 FB CC 00 00 00 00 00 00 6B 70 ";
        //String dataStr="01 03 1A 42 54 31 30 36 30 30 32 34 33 30 4C 54 30 30 32 31 30 37 33 31 30 30 31 00 00 E3 82";
        //String dataStr="30 30 32 31 30 37 33 31 30 30 31 00 00 E3 82";
        //String dataStr="03 03 A0 63 01 00 01 0B C8 00 00 DA C0 00 00 00 00 26 26 00 00 23 A0 00 00 5D C0 00 00 00 06 01 FE 00 00 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DE 0C DD 0C DD 0C DE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 D2 0B 4F 00 00 86 A0 00 00 EA 60 00 F0 17 E8 C0 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4C 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 2E 19 5E 00 5D C0 00 00 FB CC 00 00 00 00 00 00 9C B1";
        //String dataStr="01 03 03 E8 00 02 6C 17";
        //String dataStr="04 03 A0 5F 01 00 00 0B A4 00 00 C4 0B 00 00 13 57 31 31 00 00 21 2F 00 00 43 4E 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 11 0D 12 0D 11 0D 12 0D 11 0D 12 0D 13 0D 13 0D 13 0D 12 0D 12 0D 12 0D 13 0D 11 0D 0F 00 00 00 0A FF FF 00 00 75 30 00 00 4E 20 00 00 00 00 C8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4C 46 50 20 20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 00 46 50 0B 2B 04 AE 00 00 00 00 00 00 5A 8E";
        //String dataStr="03 03 04 64 00 00 00 C6 C3";
        //String dataStr="03 03 A0 64 01 00 01 0B E8 00 00 D0 20 00 00 00 00 55 55 00 00 43 1C 00 00 4E 20 00 00 00 00 03 91 00 00 0D 02 0D 02 0D 02 0D 02 0D 03 0D 02 0D 02 0D 02 0D 03 0D 03 0D 03 0D 02 0D 02 0D 02 0D 02 0D 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 24 09 24 00 00 38 80 00 00 9C 40 00 C8 16 80 C0 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4C 69 6F 6E 00 00 00 00 00 00 00 00 00 00 00 00 2E 49 7A D1 4E 20 00 00 02 E4 00 00 00 00 00 00 D7 9D ";
        String dataStr="03 03 A0 64 01 00 00 0C 0B 00 00 DD 7F FF FF FF 70 52 52 00 00 37 09 00 00 42 68 00 00 00 00 02 A2 00 00 0D 0B 0D 0A 0D 08 0D 08 0D 0A 0D 0A 0D 0A 0D 0A 0D 09 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 0A 0D 09 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 01 00 00 75 30 00 01 38 80 01 F4 17 93 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 73 61 6E 79 75 61 6E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B9 E1 F6 52 C7 C3 ";

        String[] dataArray = dataStr.split(" ");
        byte[] data = new byte[dataArray.length];
        for (int i = 0; i < dataArray.length; i++) {
            data[i] = (byte) Integer.parseInt(dataArray[i], 16);
        }

        // 创建TaitModbusParser对象
        TaitModbusParser parser = new TaitModbusParser();

        // 解析数据
        TaitModbusPowerResponse response = parser.parseBatteryData(data,null);

        // 打印解析结果
        System.out.println(response.toString());
    }
    public static String[] hexStringToArray(String hexString) {
        // 检查字符串长度是否为偶数
        if (hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("Hex string length must be even.");
        }

        // 创建数组，长度为字符串长度的一半
        String[] dataArray = new String[hexString.length() / 2];

        // 循环遍历字符串，每两位转换为一个字符串元素
        for (int i = 0; i < hexString.length(); i += 2) {
            dataArray[i / 2] = hexString.substring(i, i + 2);
        }

        return dataArray;
    }

}